Skip to content

fix: load CldVideoPlayer posters when aspectRatio is set - #674

Open
PaulBoye-py wants to merge 1 commit into
mainfrom
fix/video-player-aspect-ratio-poster
Open

PaulBoye-py wants to merge 1 commit into
mainfrom
fix/video-player-aspect-ratio-poster

Conversation

@PaulBoye-py

@PaulBoye-py PaulBoye-py commented Nov 8, 2026 •

Copy link
Copy Markdown
Collaborator

Description

With Video Player v4 (next-cloudinary 7.0.0), setting aspectRatio on CldVideoPlayer makes the poster image fail to load (Cloudinary returns a 400). The video itself plays normally. This is listed as a known limitation in the 7.0.0 release notes, with cropMode="fill" as the workaround.

Root cause:

  • getVideoPlayerOptions (url-loader) passes the transformation to the player as an array: [{ quality }, ...transformation].
  • The player turns each array item into its own URL step, and adds the aspectRatio as one more step on its own. The poster URL then ends with an ar_16:9 step that has no crop, which Cloudinary rejects for images: …/poster?tx=q_auto/ar_16:9/c_limit,w_700 (400).
  • Passing a single transformation object instead puts everything in one step, which is what the player team recommends (cloudinary-video-player#1087): …/poster?tx=ar_16:9,c_limit,q_auto,w_700 (200).

Changes:

  • New internal helper getPlayerTransformation (in the CldVideoPlayer folder, not exported from the package). When aspectRatio is set and the transformation prop isn't an array, it combines the array from getVideoPlayerOptions into one object. In every other case it returns the transformation unchanged.
  • CldVideoPlayer passes its options through the helper. The logic lives in a separate file so it can be unit tested without a DOM test setup.
  • The fix is in next-cloudinary only, not in url-loader, so the Svelte and Astro SDKs (which also use getVideoPlayerOptions) are unaffected.

What changes for users:

  • Players without aspectRatio: no change. Poster and video URLs are exactly the same as in 7.0.0.
  • Players with aspectRatio: the poster loads again. Their poster and video URLs change (one step instead of several), so Cloudinary generates them once under the new URLs. In testing, the delivered video was identical.
  • Players using the 7.0.0 workaround (aspectRatio with cropMode="fill"): posters already worked and still do. Their URLs change too, and the workaround can be removed.
  • aspectRatio with a transformation array: not changed by this PR (the poster still fails), because combining the user's own steps could change what they asked for. Tracked in CldVideoPlayer: poster fails with aspectRatio and a transformation array #675, which also has a tested workaround.

Issue Ticket Number

Fixes the "Known limitation" in the 7.0.0 release notes. Upstream context: cloudinary-video-player#1087.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Fix or improve the documentation
  • This change requires a documentation update

Checklist

  • I have followed the contributing guidelines of this project as mentioned in CONTRIBUTING.md
  • I have created an issue ticket for this PR
  • I have checked to ensure there aren't other open Pull Requests for the same update/change?
  • I have performed a self-review of my own code
  • I have run tests locally to ensure they all pass
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes needed to the documentation

Testing

Unit tests (tests/components/getPlayerTransformation.spec.js, 5 cases). They use the real getVideoPlayerOptions, so a change in url-loader's output would show up here:

  • no aspectRatio → transformation array unchanged
  • aspectRatio + transformation object → one object (with quality)
  • aspectRatio without a transformation → one object
  • aspectRatio + cropMode + quality → one object
  • aspectRatio + transformation array → unchanged

With the fix switched off, the 3 aspectRatio cases fail. Full suite: 21/21 pass.

Browser: 14 CldVideoPlayer scenarios in the Next.js 16 test app (Video Player 4.1.2), compared with 7.0.0:

Scenario 7.0.0 poster This PR poster URLs
aspectRatio="16:9" ❌ 400 ✅ changed
aspectRatio + transformation object ❌ 400 ✅ changed
aspectRatio + cropMode="fill" (workaround) ✅ ✅ changed
aspectRatio + transformation array ❌ 400 ❌ 400 unchanged
10 scenarios without aspectRatio (sizes, poster string/object, transformation object/array, quality, player options, controls, responsive, missing asset) same as 7.0.0 same as 7.0.0 unchanged

Videos play in all scenarios except the deliberately missing asset. No page errors.

Build: library builds; no type errors in src/; test:app (Next.js 16 production build) passes. The helper doesn't appear in the published type declarations.

The player splits a transformation array into separate URL steps and adds aspectRatio as a step of its own, which Cloudinary rejects for poster images. When aspectRatio is set and the transformation prop isn't an array, pass the player a single transformation object. Players without aspectRatio keep their existing URLs. See cloudinary/cloudinary-video-player#1087
@vercel

vercel Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
next-cloudinary Ready Ready Preview Nov 8, 2026 11:42am UTC

Request Review

This branch was successfully deployed

1 active deployment
Preview — 7cc59b39 Deployed Nov 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant